package com.mdd.system.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.query.MPJQueryWrapper;
import com.mdd.common.base.page.PageValidate;
import com.mdd.common.core.PageResult;
import com.mdd.common.util.ListUtils;
import com.mdd.system.RtAdminThreadLocal;
import com.mdd.system.entity.SystemAuthAdmin;
import com.mdd.system.entity.SystemAuthDept;
import com.mdd.system.entity.SystemAuthMenu;
import com.mdd.system.mapper.SystemAuthMenuMapper;
import com.mdd.system.service.ISystemAuthMenuService;
import com.mdd.system.service.ISystemAuthPermService;
import com.mdd.system.validate.SystemMenuCreateValidate;
import com.mdd.system.validate.SystemMenuUpdateValidate;
import com.mdd.system.vo.SystemAuthAdminInformVo;
import com.mdd.system.vo.SystemAuthMenuVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统菜单服务实现类
 */
@Service
public class SystemAuthMenuServiceImpl extends ServiceImpl<SystemAuthMenuMapper,SystemAuthMenu> implements ISystemAuthMenuService {

    @Resource
    SystemAuthMenuMapper systemAuthMenuMapper;

    @Resource
    ISystemAuthPermService iSystemAuthPermService;

    /**
     * 根据角色ID获取菜单
     *
     * @author fzr
     * @param roleIds 角色ID
     * @return JSONArray
     */
    @Override
    public JSONArray selectMenuByRoleId(Long roleIds) {
        Long adminId = RtAdminThreadLocal.getAdminId();
        List<Long> menuIds = iSystemAuthPermService.selectMenuIdsByRoleId(roleIds);

        QueryWrapper<SystemAuthMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("menu_type", Arrays.asList("M", "C"));
        queryWrapper.orderByDesc("menu_sort");
        queryWrapper.orderByAsc("id");
        if (!adminId.equals(1L)) {
            if (menuIds.size() <= 0) {
                menuIds.add(0L);
            }
            queryWrapper.in("id", menuIds);
        }

        List<SystemAuthMenu> systemAuthMenus = systemAuthMenuMapper.selectList(queryWrapper);

        List<SystemAuthMenuVo> lists = new ArrayList<>();
        for (SystemAuthMenu systemAuthMenu : systemAuthMenus) {
            SystemAuthMenuVo vo = new SystemAuthMenuVo();
            BeanUtils.copyProperties(systemAuthMenu, vo);
            lists.add(vo);
        }

        JSONArray jsonArray = JSONArray.parseArray(JSONArray.toJSONString(lists));
        return ListUtils.listToTree(jsonArray, "id", "pid", "children");
    }

    /**
     * 菜单列表
     *
     * @author fzr
     * @return JSONArray
     */
    @Override
    public JSONArray list(SystemAuthAdminInformVo systemAuthAdmin) {
        List<Long> ids = iSystemAuthPermService.selectMenuIdsByRoleId(systemAuthAdmin.getRoleIds());
        QueryWrapper<SystemAuthMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("menu_sort");
        //queryWrapper.in("menu_type","M","C");
        queryWrapper.orderByAsc("id");

        List<SystemAuthMenu> systemAuthMenus = systemAuthMenuMapper.selectBatchIds(ids);

        //admin查询所有菜单
        if(systemAuthAdmin.getId().equals(1L)){
            systemAuthMenus = systemAuthMenuMapper.selectList(new LambdaQueryWrapper<>());
        }

        List<SystemAuthMenuVo> lists = new ArrayList<>();
        for (SystemAuthMenu systemAuthMenu : systemAuthMenus) {
            SystemAuthMenuVo vo = new SystemAuthMenuVo();
            BeanUtils.copyProperties(systemAuthMenu, vo);

            lists.add(vo);
        }

        JSONArray jsonArray = JSONArray.parseArray(JSONArray.toJSONString(lists));
        return ListUtils.listToTree(jsonArray, "id", "pid", "children");
    }

    @Override
    public PageResult<SystemAuthMenuVo> listPage(PageValidate pageValidate ) {
        Integer page  = pageValidate.getPageNo();
        Integer limit = pageValidate.getPageSize();
        MPJQueryWrapper<SystemAuthDept> queryWrapper = new MPJQueryWrapper<>();
        queryWrapper.select("id, pid, menu_type, menu_name, menu_icon, menu_sort, perms, paths, component, selected, params, is_cache, is_show, is_disable, create_time, update_time ");
        queryWrapper.eq("pid",0);
        queryWrapper.orderByDesc(Arrays.asList("menu_sort", "id"));
        IPage<SystemAuthMenu> iPage = systemAuthMenuMapper.selectJoinPage(new Page<>(page, limit),
                SystemAuthMenu.class,queryWrapper);
        List<SystemAuthMenuVo> list = new LinkedList<>();
        for(SystemAuthMenu systemAuthMenu : iPage.getRecords()){
            SystemAuthMenuVo systemAuthMenuVo = new SystemAuthMenuVo();
            BeanUtils.copyProperties(systemAuthMenu,systemAuthMenuVo);
            generateSystemAuthMenuVoDeptVo(systemAuthMenuVo);
            list.add(systemAuthMenuVo);
        }

        return   PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), list);
    }
    /**
     * 菜单详情
     *
     * @author fzr
     * @param id 主键参数
     * @return SysMenu
     */
    @Override
    public SystemAuthMenuVo detail(Long id) {
        SystemAuthMenu systemAuthMenu = systemAuthMenuMapper.selectOne(new QueryWrapper<SystemAuthMenu>().eq("id", id));
        Assert.notNull(systemAuthMenu, "菜单已不存在!");

        SystemAuthMenuVo vo  = new SystemAuthMenuVo();
        BeanUtils.copyProperties(systemAuthMenu, vo);

        return vo;
    }

    /**
     * 新增菜单
     *
     * @author fzr
     * @param createValidate 参数
     */
    @Transactional
    @Override
    public void add(SystemMenuCreateValidate createValidate) {
        SystemAuthMenu model = new SystemAuthMenu();
        model.setPid(createValidate.getPid());
        model.setMenuType(createValidate.getMenuType());
        model.setMenuName(createValidate.getMenuName());
        model.setMenuIcon(createValidate.getMenuIcon());
        model.setMenuSort(createValidate.getMenuSort());
        model.setPerms(createValidate.getPerms());
        model.setPaths(createValidate.getPaths());
        model.setComponent(createValidate.getComponent());
        model.setSelected(createValidate.getSelected());
        model.setParams(createValidate.getParams());

        model.setIsCache(1);
        model.setIsShow(1);

        model.setIsDisable(createValidate.getIsDisable());
        systemAuthMenuMapper.insert(model);

        iSystemAuthPermService.batchSaveByMenuIds(RtAdminThreadLocal.getRoleIds(),model.getId().toString());
    }

    /**
     * 编辑菜单
     *
     * @author fzr
     * @param updateValidate 菜单
     */
    @Transactional
    @Override
    public void edit(SystemMenuUpdateValidate updateValidate) {
        SystemAuthMenu model = systemAuthMenuMapper.selectOne(new QueryWrapper<SystemAuthMenu>().eq("id", updateValidate.getId()));
        Assert.notNull(model, "菜单已不存在!");

        model.setMenuType(updateValidate.getMenuType());
        model.setMenuName(updateValidate.getMenuName());
        model.setMenuIcon(updateValidate.getMenuIcon());
        model.setMenuSort(updateValidate.getMenuSort());
        model.setPaths(updateValidate.getPaths());
        model.setPerms(updateValidate.getPerms());
        model.setComponent(updateValidate.getComponent());
        model.setPid(updateValidate.getPid());
        model.setSelected(updateValidate.getSelected());
        model.setParams(updateValidate.getParams());
//        model.setIsCache(updateValidate.getIsCache());
//        model.setIsShow(updateValidate.getIsShow());
        model.setIsDisable(updateValidate.getIsDisable());
        systemAuthMenuMapper.updateById(model);
    }

    /**
     * 删除菜单
     *
     * @author fzr
     * @param id 主键参数
     */
    @Transactional
    @Override
    public void del(Long id) {
        SystemAuthMenu model = systemAuthMenuMapper.selectOne(
                new QueryWrapper<SystemAuthMenu>()
                        .select("id,pid,menu_name")
                        .eq("id", id)
                        .last("limit 1"));

        Assert.notNull(model, "菜单已不存在!");
        Assert.isNull(systemAuthMenuMapper.selectOne(
                new QueryWrapper<SystemAuthMenu>()
                        .eq("pid", id)
                        .last("limit 1")),
                "请先删除子菜单再操作!");

        systemAuthMenuMapper.deleteById(id);
        iSystemAuthPermService.batchDeleteByMenuId(id);
    }

    /**
     * 构建父子结构
     * @param parentVo
     * @return
     */
    private SystemAuthMenuVo generateSystemAuthMenuVoDeptVo(SystemAuthMenuVo parentVo) {
        QueryWrapper<SystemAuthMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pid",parentVo.getId());
        queryWrapper.orderByDesc(Arrays.asList("menu_sort", "id"));
        List<SystemAuthMenu> childD = systemAuthMenuMapper.selectList(queryWrapper);
        if(childD!=null && !childD.isEmpty()){
            List<SystemAuthMenuVo> list = childD.stream().map(dept -> {
                        SystemAuthMenuVo systemAuthMenuVo1 =  new SystemAuthMenuVo();
                        BeanUtils.copyProperties(dept,systemAuthMenuVo1);
                        generateSystemAuthMenuVoDeptVo(systemAuthMenuVo1);
                        return  systemAuthMenuVo1;
                    })
                    .collect(Collectors.toList());
            parentVo.setChildren(list);
        }
        return  parentVo;
    }
}
